package io.hellsinger.vortex.ui.component.trail

import android.view.View.OnClickListener
import android.view.View.OnLongClickListener
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import io.hellsinger.vortex.data.model.PathItem
import io.hellsinger.vortex.data.model.name
import io.hellsinger.vortex.ui.component.adapter.ItemViewProvider
import io.hellsinger.vortex.ui.component.adapter.Items
import io.hellsinger.vortex.ui.component.adapter.SingleTypeAdapter
import io.hellsinger.vortex.ui.component.adapter.listener.ItemListener

class TrailAdapter(
    private val listener: ItemListener,
    private val viewProvider: ItemViewProvider<TrailItemView> =
        ItemViewProvider { parent, viewType ->
            TrailItemView(
                parent.context,
            )
        },
) : SingleTypeAdapter<PathItem, TrailViewHolder>() {
    private val clickListenerWrapper =
        OnClickListener { view ->
            listener.onItemClick(view, view.tag as Int)
        }

    private val longClickListenerWrapper =
        OnLongClickListener { view ->
            return@OnLongClickListener listener.onLongItemClick(view, view.tag as Int)
        }

    var selected: Int = -1
        private set

    fun updateSelected(index: Int) {
        notifyItemChanged(index)
        val old = selected
        selected = index
        notifyItemChanged(old)
    }

    override fun getItemId(position: Int): Long = list[position].id

    override fun createDiffer(new: List<PathItem>): DiffUtil.Callback = Differ(list, new)

    override fun createViewHolder(parent: ViewGroup): TrailViewHolder = TrailViewHolder(viewProvider.provide(parent, Items.NO_TYPE))

    override fun onViewAttachedToWindow(holder: TrailViewHolder) {
        holder.root.onBindListener(clickListenerWrapper)
        holder.root.onBindLongListener(longClickListenerWrapper)
    }

    override fun onViewDetachedFromWindow(holder: TrailViewHolder) {
        holder.root.onBindListener(null)
        holder.root.onBindLongListener(null)
    }

    override fun onBindViewHolder(
        holder: TrailViewHolder,
        position: Int,
    ) {
        val item = list[position]
        with(holder.itemView as TrailItemView) {
            title = item.name
            tag = holder.bindingAdapterPosition

            onBindSelection(selected == position)
            isArrowVisible = position != list.lastIndex
        }
    }

    override fun getItemCount(): Int = list.size

    class Differ(
        private val old: List<PathItem>,
        private val new: List<PathItem>,
    ) : DiffUtil.Callback() {
        override fun getOldListSize(): Int = old.size

        override fun getNewListSize(): Int = new.size

        override fun areItemsTheSame(
            oldItemPosition: Int,
            newItemPosition: Int,
        ) = old[oldItemPosition].id == new[newItemPosition].id

        override fun areContentsTheSame(
            oldItemPosition: Int,
            newItemPosition: Int,
        ): Boolean {
            val old = old[oldItemPosition]
            val new = new[newItemPosition]
            return old == new
        }
    }
}
